package com.zp.manager.disruptor;

import cn.hutool.json.JSONUtil;
import com.lmax.disruptor.WorkHandler;
import com.zp.domain.entity.User;
import com.zp.enums.PictureEditMessageTypeEnum;
import com.zp.manager.websocket.PictureEditHandler;
import com.zp.manager.websocket.PictureEditRequestMessage;
import com.zp.manager.websocket.PictureEditResponseMessage;
import com.zp.service.UserService;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import javax.annotation.Resource;

/**
 * 消费者: 处理消息(事件处理器)
 */
@Component
public class PictureEditEventWorkHandler implements WorkHandler<PictureEditEvent> {
    @Resource
    @Lazy
    private PictureEditHandler pictureEditHandler;

    @Resource
    private UserService userService;

    @Override
    public void onEvent(PictureEditEvent event) throws Exception {
        PictureEditRequestMessage requestMessage = event.getPictureEditRequestMessage();
        WebSocketSession session = event.getSession();
        User user = event.getUser();
        Long pictureId = event.getPictureId();
        // 2. 从 PictureEditRequestMessage 拿到消息类型, 确定是什么操作
        String type = requestMessage.getType();
        PictureEditMessageTypeEnum messageTypeEnum = PictureEditMessageTypeEnum.getEnumByValue(type);
        switch (messageTypeEnum) {
            case ENTER_EDIT:
                // 进入编辑状态
                pictureEditHandler.handleEnterEditMessage(user, pictureId);
                break;
            case EDIT_ACTION:
                // 执行编辑操作
                pictureEditHandler.handleEditActionMessage(requestMessage, session, user, pictureId);
                break;
            case EXIT_EDIT:
                // 退出编辑状态
                pictureEditHandler.handleExitEditMessage(session, user, pictureId);
                break;
            default:
                // 其他消息类型, 返回错误提示
                PictureEditResponseMessage responseMessage = PictureEditResponseMessage.builder()
                        .type(PictureEditMessageTypeEnum.ERROR.getValue())
                        .message("消息类型错误")
                        .user(userService.getUserVO(user))
                        .build();
                // 严格来说还是使用 ObjectMapper 处理序列化, 避免精度丢失, 但是这是错误消息, 精度丢失也没关系
                session.sendMessage(new TextMessage(JSONUtil.toJsonStr(responseMessage)));
                break;
        }
    }
}

